import { Context, Next } from "hono";
import * as jwt from "jsonwebtoken";
import Responder from "./response";
import { AuthService } from "../services/auth";

const JWT_SECRET = process.env.JWT_SECRET || "your-secret-key";
const authService = new AuthService();

interface JwtPayload {
  userId: string;
  email: string;
  exp?: number;
  iat?: number;
}

declare module "hono" {
  interface ContextVariableMap {
    userId: string;
  }
}

export async function authMiddleware(c: Context, next: Next) {
  try {
    // 1. 检查 Authorization header 是否存在
    const auth = c.req.header("Authorization");
    if (!auth) {
      return Responder.fail("未提供认证信息")
        .setStatusCode(401)
        .setErrors(["NO_AUTH_HEADER"])
        .build(c);
    }

    // 2. 检查 Bearer token 格式
    if (!auth.startsWith("Bearer ")) {
      return Responder.fail("认证格式错误")
        .setStatusCode(401)
        .setErrors(["INVALID_AUTH_FORMAT"])
        .build(c);
    }

    const token = auth.split(" ")[1];
    if (!token) {
      return Responder.fail("Token不能为空")
        .setStatusCode(401)
        .setErrors(["EMPTY_TOKEN"])
        .build(c);
    }

    try {
      // 3. 验证 token
      const decoded = jwt.verify(token, JWT_SECRET) as JwtPayload;

      // 4. 检查 token 是否过期
      const now = Math.floor(Date.now() / 1000);
      if (decoded.exp && decoded.exp < now) {
        return Responder.fail("Token已过期")
          .setStatusCode(401)
          .setErrors(["TOKEN_EXPIRED"])
          .build(c);
      }

      // 5. 验证用户是否存在
      try {
        const user = await authService.getUserById(decoded.userId);
        if (!user) {
          return Responder.fail("用户不存在")
            .setStatusCode(401)
            .setErrors(["USER_NOT_FOUND"])
            .build(c);
        }

        // 6. 设置用户信息到上下文
        c.set("userId", decoded.userId);

        // 7. 检查 token 是否即将过期（如果离过期时间不到 1 小时，返回新 token）
        const oneHour = 3600;
        if (decoded.exp && decoded.exp - now < oneHour) {
          const newToken = jwt.sign(
            { userId: decoded.userId, email: decoded.email },
            JWT_SECRET,
            { expiresIn: "24h" }
          );
          c.header("New-Token", newToken);
        }

        await next();
      } catch (error) {
        return Responder.fail("用户验证失败")
          .setStatusCode(401)
          .setErrors(["USER_VALIDATION_FAILED"])
          .build(c);
      }
    } catch (error) {
      if (error instanceof jwt.TokenExpiredError) {
        return Responder.fail("Token已过期")
          .setStatusCode(401)
          .setErrors(["TOKEN_EXPIRED"])
          .build(c);
      }
      if (error instanceof jwt.JsonWebTokenError) {
        return Responder.fail("Token无效")
          .setStatusCode(401)
          .setErrors(["INVALID_TOKEN"])
          .build(c);
      }
      return Responder.fail("Token验证失败")
        .setStatusCode(401)
        .setErrors(["TOKEN_VALIDATION_FAILED"])
        .build(c);
    }
  } catch (error) {
    return Responder.fail("认证过程发生错误")
      .setStatusCode(500)
      .setErrors(["AUTH_ERROR"])
      .build(c);
  }
}
